//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// http://enbdev.com
// Modifications made by Tansarville
// Sharpening shader by CeeJay.dk, ported by r
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
// THIS IS HLSL FILE FORMAT FOR EXECUTING ADDITIONAL
// POST PROCESSING EFFECTS. MAKE THE COPY BEFORE CHANGING IT!
 
// -- Sharpening --
#define sharp_strength 1.0 // Strength of the sharpening - You should probably use something between 0.2 and 2.0 - default is 0.7
#define sharp_clamp 0.02  // Limits maximum amount of sharpening a pixel recieves - Default is 0.050
// -- Advanced sharpening settings
#define pattern 4  // Choose a sample pattern ( 1, 2, 3 or 4 ) - I suggest 2
#define offset_bias 1.0    // I suggest a value between 0.0 and 2.0 - default is 1.0
 
#define CoefLuma float4(0.2126, 0.7152, 0.0722, 0) // BT.709 & sRBG luma coefficient (Monitors and HD Television)
//#define CoefLuma float4(0.299, 0.587, 0.114, 0) // BT.601 luma coefficient (SD Television)
//#define CoefLuma float4(0.3333, 0.3334, 0.3333, 0) // Equal weight coefficient
 
#define sharp_strength_luma (CoefLuma * sharp_strength)
 
float2 fvTexelSize = float2(1.0 / 1920.0, 1.0 / 1280.0);        // set your resolution here
 
//enable noise // in dark areas
#define ENOISE
#define NoiseAmount 0.0 // 0.4 // 0.5
 
#define UseCoefForNoiseCalculations
#define noise_strength_luma (CoefLuma * NoiseAmount)
 
// The following relate to the old code
//enable sharpening
#define ESHARPENING
float SamplingRange=1.0; //sharpening or blurring range
float SharpeningAmount=1.0;
 
//x=generic timer in range 0..1, period of 16777216 ms (4.6 hours), w=frame time elapsed (in seconds)
float4  Timer;
 
//keyboard controled variables
float tempF1;
float tempF2;
float tempF3;
float tempF4;
float tempF5;
float tempF6;
float tempF7;
float tempF8;
float tempF9;
float tempF0;
 
//global variables, already set before executing this code
//float4 ScreenSize; //width of the display resolution (1920 f.e.)
float4 ScreenSize; //width, 1/width, width/height, height/width
 
//textures
texture2D texColor;
texture2D texNoise;
 
sampler2D SamplerColor = sampler_state
{
Texture   = <texColor>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = NONE;//NONE;
AddressU  = Clamp;
AddressV  = Clamp;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};
 
sampler2D SamplerNoise = sampler_state
{
Texture   = <texNoise>;
MinFilter = POINT;
MagFilter = POINT;
MipFilter = NONE;//NONE;
AddressU  = Wrap;
AddressV  = Wrap;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};
 
 
struct VS_OUTPUT_POST {
float4 vpos  : POSITION;
float2 txcoord : TEXCOORD0;
};
 
struct VS_INPUT_POST {
float3 pos  : POSITION;
float2 txcoord : TEXCOORD0;
};
 
 
 
 
 
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
VS_OUTPUT_POST VS_PostProcess(VS_INPUT_POST IN)
{
VS_OUTPUT_POST OUT;
 
float4 pos=float4(IN.pos.x,IN.pos.y,IN.pos.z,1.0);
 
OUT.vpos=pos;
OUT.txcoord.xy=IN.txcoord.xy;
 
return OUT;
}
 
// New sharpen pixel shader - by CeeJay.dk
float4 PS_ProcessPass_Sharpen(VS_OUTPUT_POST IN, float2 vPos : VPOS, float2 tex : TEXCOORD0) : COLOR
{
        float2 coord = IN.txcoord.xy;
       
  #define px fvTexelSize.x //one_over_width
  #define py fvTexelSize.y //one_over_height
 
//      float one_over_height = float ((ScreenSize.w * ScreenSize.x) / 1);   
//      #define px ScreenSize.x //one_over_width
//      #define py one_over_height //one_over_height
       
        half4 ori = tex2D(SamplerColor, coord.xy);
 
        [branch] if (any(frac(ori.rgb)))
        {
  #if pattern == 1
 
        // -- Gaussian filter --
        //   [ 2/9, 4/9,    ]     [ 1 , 2 ,   ]
        //   [ 4/9, 8/9, 4/9]  =  [ 2 , 4 , 2 ]
        //   [    , 2/9, 2/9]     [   , 2 , 1 ]
       
    half4 blur_ori = tex2Dlod(SamplerColor, float4(tex,tex) + float4(-px,py,-px,py) / 3 * offset_bias); // North West
    blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(px,-py,px,-py) / 3 * offset_bias);  // South East
    //blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(px,py,px,py) / 3 * offset_bias); // North East
        //blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(-px,-py,-px,-py) / 3 * offset_bias); // South West
 
    blur_ori /= 2;  //Divide by the number of texture fetches
  #endif
 
  // -- Pattern 2 -- A 9 tap gaussian using 4+1 texture fetches.
  #if pattern == 2
        // -- Gaussian filter --
        //   [ .25, .50, .25]     [ 1 , 2 , 1 ]
        //   [ .50,   1, .50]  =  [ 2 , 4 , 2 ]
        //   [ .25, .50, .25]     [ 1 , 2 , 1 ]
 
    half4 blur_ori = tex2Dlod(SamplerColor, float4(tex,tex) + float4(-px,py,-px,py) * 0.5 * offset_bias); // North West
    blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(px,-py,px,-py) * 0.5 * offset_bias);  // South East
 
        if (any((blur_ori.rgb / 2) - ori.rgb))
        {
        blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(-px,-py,-px,-py) * 0.5 * offset_bias); // South West
        blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(px,py,px,py) * 0.5 * offset_bias); // North East
        blur_ori /= 2;  //Divide by the number of texture fetches
        }
 
    blur_ori /= 2;  //Divide by the number of texture fetches
 
  #endif
 
  // -- Pattern 3 -- An experimental 17 tap gaussian using 4+1 texture fetches.
  #if pattern == 3
 
        // -- Gaussian filter --
        //   [   , 4 , 6 ,   ,   ]
        //   [   ,16 ,24 ,16 , 4 ]
        //   [ 6 ,24 ,50 ,24 , 6 ]
        //   [ 4 ,16 ,24 ,16 ,   ]
        //   [   ,   , 6 , 4 ,   ]
 
    half4 blur_ori = tex2Dlod(SamplerColor, float4(tex,tex) + float4(-0.4*px,1.2*py,-0.4*px,1.2*py) * offset_bias); // North North West
    blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(0.4*px,-1.2*py,0.4*px,-1.2*py) * offset_bias);  // South South East
    blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(1.2*px,0.4*py,0,0) * offset_bias); // East North East
    blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(-1.2*px,-0.4*py,0,0) * offset_bias); // West South West
    blur_ori += ori; // Probably not needed. Only serves to lessen the effect.
   
    blur_ori /= 5;  //Divide by the number of texture fetches
  #endif
 
  // -- Pattern 4 -- A 9 tap high pass using 4+1 texture fetches.
  #if pattern == 4
 
        // -- Gaussian filter --
        //   [ .50, .50, .50]     [ 1 , 1 , 1 ]
        //   [ .50,    , .50]  =  [ 1 ,   , 1 ]
        //   [ .50, .50, .50]     [ 1 , 1 , 1 ]
 
    half4 blur_ori = tex2Dlod(SamplerColor, float4(tex,tex) + float4(0.5 * -px,py,0.5 * -px,py)); // North North West
    blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(0.5 * px,-py,0.5 * px,-py));  // South South East
    blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(-px,0.5 * -py,-px,0.5 * -py)); // West South West
    blur_ori += tex2Dlod(SamplerColor, float4(tex,tex) + float4(px,0.5 * py,px,0.5 * py)); // East North East
    blur_ori += (2 * ori); // Probably not needed. Only serves to lessen the effect.
       
 
    blur_ori /= 6;  //Divide by the number of texture fetches
  #endif
 
 // -- Pattern 99 -- A debugging pattern - This is not the pattern you are looking for .. move along.
  #if pattern == 99
 
        // -- Gaussian filter --
        //   [ .25, .50, .25]     [ 1 , 2 , 1 ]
        //   [ .50,   1, .50]  =  [ 2 , 4 , 2 ]
        //   [ .25, .50, .25]     [ 1 , 2 , 1 ]
 
    half4 blur_ori = tex2Dlod(SamplerColor, float4(tex,0,0) + float4(-px,py,0,0) * 0.5 * offset_bias); // North West
    blur_ori += tex2Dlod(SamplerColor, float4(tex,0,0) + float4(px,-py,0,0) * 0.5 * offset_bias);  // South East
 
    half3 debug1 = (blur_ori.rgb / 2) - ori.rgb;
 
    blur_ori += tex2Dlod(SamplerColor, float4(tex,0,0) + float4(-px,-py,0,0) * 0.5 * offset_bias); // South West
    blur_ori += tex2Dlod(SamplerColor, float4(tex,0,0) + float4(px,py,0,0) * 0.5 * offset_bias); // North East
     
    blur_ori /= 4;  //Divide by the number of texture fetches
 
    half3 debug2 = blur_ori.rgb - ori.rgb;
 
        debug1 = abs(debug1 - debug2);
        half debug3 = dot(debug1, sharp_strength_luma);
        if ((debug3 * 255) > 1)
        {
        blur_ori = half4(1,0.5,0,debug3);
        ori = half4(1,0.5,0,debug3);   
        }
  #endif
               
          // -- Calculate the sharpening -- 
          half sharp = ori - blur_ori;  //Subtracting the blurred image from the original image
                  
          // -- Adjust strength of the sharpening --
          sharp = dot(sharp, sharp_strength_luma); //Calculate the luma and adjust the strength
 
          // -- Clamping the maximum amount of sharpening to prevent halo artifacts --
          sharp = clamp(sharp, -sharp_clamp, sharp_clamp);  //TODO Try a curve function instead of a clamp
 
          // -- Combining the values to get the final sharpened pixel   --
          half4 done = ori + sharp;    // Add the sharpening to the original.  //Wait shouldn't I be adding it to luma and then add chroma?
                
// .------------------------------------------------._Debugging and tweaking.-----------------------------------------------.
 
  //For tweaking and debugging purposes you can show the sharpen effect or chroma.
  //float4 done = (sharp*4) + float4(0.5,0.5,0.5,0);  // Uncomment to visualize the strength of the sharpen (multiplied by 4 to see it better)
 
  //done = ori.a;         // Visualize the alpha
  //done = 1.0 - ori.a;  //  Visualize the inverted alpha
  //done = float4(done.rgb, ori.a);       
                
// .-------------------------------------------------._Returning the output_.-----------------------------------------------.
 
                  return done;
                  }
          else
          {
                //return half4(1,1,0,1);
                return ori;
          }
        }
 
float4 PS_PostProcess_Noise(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
float4 coord=0.0;
 
coord.xy=IN.txcoord.xy;
coord.w=0.0;
 
/*
float4 origcolor;
origcolor=tex2Dlod(SamplerColor, coord);
 
float4 tcol=origcolor;
*/
 
float4 tcol=tex2Dlod(SamplerColor, coord);
 
float origgray=max(tcol.x, tcol.y);//dot(tcol.xyz, 0.333);
origgray=max(origgray, tcol.z);
#define NoiseFineness 18.0 // 16.0
coord.xy=IN.txcoord.xy*NoiseFineness + frac(Timer.x * 100000.0 + Timer.x);
float4 cnoi=tex2Dlod(SamplerNoise, coord);
 
// Noise everywhere:
// tcol=lerp(tcol, (cnoi.x+0.5)*tcol, NoiseAmount*saturate(1.0-origgray*0.5));
// Noise only in dark places:
// tcol=lerp(tcol, (cnoi.x+0.5)*tcol, NoiseAmount*saturate(0.8-origgray*1.8));
 
#ifdef UseCoefForNoiseCalculations
tcol=lerp(tcol, (cnoi.x+0.5)*tcol, noise_strength_luma*saturate(1.0-origgray*0.5));
/* This doesn't work
float noiseFact1 <
   string UIName="noiseFact1";
   string UIWidget="Spinner";
   float UIMin=-2.0;
   float UIMax=2.0;
> = 1.0
float noiseFact2 <
   string UIName="noiseFact2";
   string UIWidget="Spinner";
   float UIMin=-2.0;
   float UIMax=2.0;
> = 0.5
tcol=lerp(tcol, (cnoi.x+0.5)*tcol, noise_strength_luma*saturate(noiseFact1-origgray*noiseFact2));
*/
#else
tcol=lerp(tcol, (cnoi.x+0.5)*tcol, NoiseAmount*saturate(1.0-origgray*0.5));
#endif
 
tcol.w=1.0;
return tcol;
}
 
 
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Two-pass shader
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#ifdef ENOISE
technique PostProcess
{
   pass P0
   {
 
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader  = compile ps_3_0 PS_PostProcess_Noise();
 
                        DitherEnable = FALSE;
                        ZEnable = FALSE;
                        CullMode = NONE;
                        ALPHATESTENABLE = FALSE;
                        SEPARATEALPHABLENDENABLE = FALSE;
                        AlphaBlendEnable = FALSE;
                        StencilEnable = FALSE;
                        FogEnable = FALSE;
                        SRGBWRITEENABLE = FALSE;
}
}
#endif
 
technique PostProcess2
{
   pass P0
   {
 
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader  = compile ps_3_0 PS_ProcessPass_Sharpen();
 
                        DitherEnable = FALSE;
                        ZEnable = FALSE;
                        CullMode = NONE;
                        ALPHATESTENABLE = FALSE;
                        SEPARATEALPHABLENDENABLE = FALSE;
                        AlphaBlendEnable = FALSE;
                        StencilEnable = FALSE;
                        FogEnable = FALSE;
                        SRGBWRITEENABLE = FALSE;
}
}